package com.itcast.demo.poiutils;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

public class POIUtils {
    private static final String XLS = "xls";
    private static final String XLSX = "xlsx";
    private static final String DATE_FORMAT = "yyyy/MM/dd";
    /**
     * 读excel文件，解析后返回
     */
    public static List<String[]> readExcel(MultipartFile file) throws Exception {
        // 检查文件
        checkFile(file);
        // 获得workboo工作簿对象
        Workbook workbook = getWorkBook(file);
        // 创建返回对象，把每行中的值作为一个数组，所有行作为一个集合返回
        ArrayList<String[]> list = new ArrayList<>();
        if(workbook ==null) {
            return list;
        }
        for(int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
            // 获得当前sheet工作表
            Sheet sheet = workbook.getSheetAt(sheetNum);
            if(sheet == null) {
                continue;
            }
            // 获得当前sheet的开始行
            int firstRowNum = sheet.getFirstRowNum();
            // 获得当前sheet的结束行
            int lastRowNum = sheet.getLastRowNum();
            // 循环除了第一行的所有行
            for(int rowNum = firstRowNum+1; rowNum <= lastRowNum; rowNum++) {
                // 获得当前行
                Row row = sheet.getRow(rowNum);
                if(row == null) {
                    continue;
                }
                // 获取当前行的1
                int firstCellNum = row.getFirstCellNum();
                // 获取当前行的最后列
                int lastCellNum = row.getPhysicalNumberOfCells();
                String[] cells = new String[row.getPhysicalNumberOfCells()];
                // 循环当前行
                for(int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
                    Cell cell = row.getCell(cellNum);
                    cells[cellNum] = getCellValue(cell);
                }
                list.add(cells);
            }
        }
        return list;
    }
    // 校验文件是否合法
    public static void checkFile(MultipartFile file) throws Exception {
        // 判断文件是否存在
        if(null == file) {
            throw new Exception("文件不存在！");
        }
        // 获得文件名
        String fileName = file.getOriginalFilename();
        // 判断文件是否是excel文件
        if(!fileName.endsWith(XLS) && !fileName.endsWith(XLSX)) {
            throw new Exception(fileName + "不是excel文件");
        }
    }
    // 获取工作簿对象
    public static Workbook getWorkBook(MultipartFile file) {
        // 获取文件名
        String fileName = file.getOriginalFilename();
        // 创建Workbook工作簿对象,表示整个excel
        Workbook workbook = null;
        try{
            // 获取excel文件的io流
            InputStream is = file.getInputStream();
            // 获取文件后缀名不同xls和xlsx，获的不同的Workbook实现类对象
            if(fileName.endsWith(XLS)) {
               workbook =  new HSSFWorkbook(is);
            }
            if(fileName.endsWith(XLSX)) {
                workbook = new XSSFWorkbook(is);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return workbook;
    }
    // 获取单元格数值
    public static String getCellValue(Cell cell) {
        String cellValue = "";
        if(cell == null) {
            return cellValue;
        }
        // 如果当前单元格内容为日期类型，需要特殊处理
        String dataFormatString = cell.getCellStyle().getDataFormatString();
        if(dataFormatString.equals("m/d/yy")) {
            cellValue = new SimpleDateFormat(DATE_FORMAT).format(cell.getDateCellValue());
            return cellValue;
        }
        if(dataFormatString.equals("m.d.yy")) {
            cellValue = new SimpleDateFormat(DATE_FORMAT).format(cell.getDateCellValue());
            return cellValue;
        }
        // 把数字当成String来读，避免出现1读成1.0的情况
        if(cell.getCellType() == CellType.NUMERIC) {
            cell.setCellType(CellType.STRING);
        }
        // 判断数据的类型
        cellValue = switch (cell.getCellType()) {
            case NUMERIC -> String.valueOf(cell.getNumericCellValue());
            case STRING -> String.valueOf(cell.getStringCellValue());
            case BOOLEAN -> String.valueOf(cell.getBooleanCellValue());
            case FORMULA -> String.valueOf(cell.getCellFormula());
            case BLANK -> "";
            case ERROR -> "非法字符";
            default -> "未知类型";
        };
        return cellValue;
    }

}
